iT邦幫忙

2023 iThome 鐵人賽

DAY 7
0

React Native 提供一種名叫 Flexbox 的方式來管理版面, Flexbox 就像合併了網頁能使用 display: flex 搭配 flex-direction 、 justify-content 等設定並排方式,與 flex: 1 1 auto 收縮或延伸這兩種功能。


display: flex

在網站中,必須設定 display: flex 後才能使用 flex-direction 等, React Native 則是已經預設好。要注意的是,他在 flexDirection 預設是 column ,而 alignContent 預設是 flex-start 。

flexDirection: column 會影響到什麼呢?要置中時使用 justifyContent 和 alignItems 要注意 justifyContent 是控制垂直, alignItems 是控制水平。

function App() {
  return (
    <View style={styles.container}>
      <View style={styles.item}></View>
    </View>
  );
}
const styles = StyleSheet.create({
  container: {
    width: '100%',
    height: '100%',
    backgroundColor: 'lightgreen',
    // justifyContent: 'center',
    alignItems: 'center',
  },
  item: {
    width: '30%',
    height: '20%',
    backgroundColor: 'darkgreen',
  },
});

https://ithelp.ithome.com.tw/upload/images/20230909/20129635BwEcE5xmoL.png

另外,他還有提供 alignContent 這個屬性。當元件有設定 flexWrap 時,裡頭的子元件們都能夠被這個屬性正確的控制擺放位置。

function App() {
  return (
    <View style={styles.container}>
      <View style={[styles.item, styles.item1]}></View>
      <View style={[styles.item, styles.item2]}></View>
      <View style={[styles.item, styles.item3]}></View>
    </View>
  );
}
const styles = StyleSheet.create({
  container: {
    width: '100%',
    height: '100%',
    backgroundColor: 'lightgreen',
    flexWrap: 'wrap',
    alignContent: 'center',
  },
  item: {
    width: '30%',
    height: '20%',
  },
  item1: {
    backgroundColor: 'darkgreen',
  },
  item2: {
    backgroundColor: 'blue',
  },
  item3: {
    backgroundColor: 'cyan',
  },
});

export default App;

https://ithelp.ithome.com.tw/upload/images/20230909/20129635wrijCvQIH1.png

若改成 alignItems: center 則不會如預期顯示:

const styles = StyleSheet.create({
  container: {
    … 省略
    alignItems: 'center', // 改這句
  },

https://ithelp.ithome.com.tw/upload/images/20230909/20129635WKMIc0T6j4.png


flex: 1

再來看第二種功能。在網站中我們能一次設定 flex: 1 1 auto ,不過在 React Native 中, flex 只支援數字值。舉例來說,如果只設定一個,那該項目會延伸直到填滿剩餘的畫面,其他沒設定的會照原先設好的 width 和 height 顯示。
https://ithelp.ithome.com.tw/upload/images/20230909/201296354ZLGKQ1Clx.png

依此類推,如果設定兩個和三個都設,會分別呈現下面的畫面。
https://ithelp.ithome.com.tw/upload/images/20230909/20129635hm3pe4SCFF.png
https://ithelp.ithome.com.tw/upload/images/20230909/20129635JVMWL9sryX.png

當然,既然三個都設 flex:1 了,也不用再設定 height ,因為會以 flex 為優先。
https://ithelp.ithome.com.tw/upload/images/20230909/2012963509To8qQcx0.png

若其中一個需佔用 50% ,另兩個佔用 25% 則可以這樣設定:
https://ithelp.ithome.com.tw/upload/images/20230909/201296359p4QQ9fumo.png

如果仍想設定 flex: 1 1 auto ,則必須分別透過 flexGrow 、 flexShrink 和 flexBasis 來各自設定。

  • flexBasis :
    他會提供一個預設的寬度(在 flexDirection 是 row 時)或高度(在 flexDirection 是 column 時),在沒有設定 flex 、 flexGrow 或 flexShrink 時會以此值顯示。

以下圖的例子來說,雖然沒設定 height ,但因有 flexBasis ,項目有基本的高度 100 。除非有進一步設定 flex ,否則就以 flexBasis 顯示。
https://ithelp.ithome.com.tw/upload/images/20230909/20129635MA2gY2WWgq.png

  • flexGrow :
    flexGrow 會在空間足夠時,無視 flexBasis 自動延伸。
    https://ithelp.ithome.com.tw/upload/images/20230909/2012963528uwihioeJ.png

所謂的「空間足夠時,自動延伸」,指的是 item3 會被壓縮成剩餘高度。我們可以改寫程式碼,在 Item 中插入文字,並讓文字水平、垂直置中,來驗證上述的話。可以發現第三個項目的垂直置中,是建立在被延伸後的高度上:

function App() {
  return (
    <View style={styles.container}>
      <View style={[styles.item, styles.item1]}>
        <Text style={styles.itemText}>1</Text>
      </View>
      <View style={[styles.item, styles.item2]}>
        <Text style={styles.itemText}>2</Text>
      </View>
      <View style={[styles.item, styles.item3]}>
        <Text style={styles.itemText}>3</Text>
      </View>
    </View>
  );
}
const styles = StyleSheet.create({
  container: {
    width: '100%',
    height: '100%',
    backgroundColor: 'lightgreen',
  },
  item: {
    width: '30%',
    justifyContent: 'center',
    alignItems: 'center',
  },
  itemText: {
    color: 'orange',
    fontSize: 30,
  },
  item1: {
    backgroundColor: 'darkgreen',
    flexBasis: 100,
  },
  item2: {
    backgroundColor: 'blue',
    flexBasis: 100,
  },
  item3: {
    backgroundColor: 'cyan',
    flexGrow: 1,
    flexBasis: 100,
  },
});

https://ithelp.ithome.com.tw/upload/images/20230909/201296356xmNdaSWma.png

  • flexShrink :
    flexShrink 會在空間不夠時自動縮減。和網站的預設不同,預設值是 0 。
    https://ithelp.ithome.com.tw/upload/images/20230909/20129635VwhXsZB1fR.png
    https://ithelp.ithome.com.tw/upload/images/20230909/20129635l0XCnQBCVD.png

所謂的「空間不夠時,以剩餘空間顯示」,指的是 item3 會被壓縮成剩餘高度。我們可以改寫程式碼,在 Item 中插入文字,並讓文字水平、垂直置中,來驗證上述的話。可以發現第三個項目的垂直置中,是建立在被壓縮後的高度上:

function App() {
  return (
    <View style={styles.container}>
      <View style={[styles.item, styles.item1]}>
        <Text style={styles.itemText}>1</Text>
      </View>
      <View style={[styles.item, styles.item2]}>
        <Text style={styles.itemText}>2</Text>
      </View>
      <View style={[styles.item, styles.item3]}>
        <Text style={styles.itemText}>3</Text>
      </View>
    </View>
  );
}
const styles = StyleSheet.create({
  container: {
    width: '100%',
    height: '100%',
    backgroundColor: 'lightgreen',
  },
  item: {
    width: '30%',
    justifyContent: 'center',
    alignItems: 'center',
  },
  itemText: {
    color: 'orange',
    fontSize: 30,
  },
  item1: {
    backgroundColor: 'darkgreen',
    flexBasis: 200,
  },
  item2: {
    backgroundColor: 'blue',
    flexBasis: 200,
  },
  item3: {
    backgroundColor: 'cyan',
    flexShrink: 1,
    flexBasis: 600,
  },
});

https://ithelp.ithome.com.tw/upload/images/20230909/20129635yI5ZdbrHZc.png


上一篇
Day 06. React Native 如何建立與調整樣式
下一篇
Day 08. 常見元件介紹
系列文
即使明天老闆突然叫你用 React Native 也可以跟他說好沒問題30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言